package com.homepig.mongodb;

import com.mongodb.MongoClient;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;

import static com.mongodb.client.model.Filters.eq;
import static com.mongodb.client.model.Projections.*;
import static java.util.Arrays.asList;

/**
 * 要从查询返回的项目字段
 *
 * @author fengchao
 */
public class QuerySpecifiedFields {
    private static MongoCollection mongoCollection;

    static {
        MongoClient mongoClient = new MongoClient("localhost", 27017);
        MongoDatabase mongoDatabase = mongoClient.getDatabase("mongo_stu");
        mongoCollection = mongoDatabase.getCollection("inventory");

        mongoCollection.drop();

        mongoCollection.insertMany(asList(
                Document.parse("{ item: 'journal', status: 'A', size: { h: 14, w: 21, uom: 'cm' }, instock: [ { warehouse: 'A', qty: 5 }]}"),
                Document.parse("{ item: 'notebook', status: 'A',  size: { h: 8.5, w: 11, uom: 'in' }, instock: [ { warehouse: 'C', qty: 5}]}"),
                Document.parse("{ item: 'paper', status: 'D', size: { h: 8.5, w: 11, uom: 'in' }, instock: [ { warehouse: 'A', qty: 60 }]}"),
                Document.parse("{ item: 'planner', status: 'D', size: { h: 22.85, w: 30, uom: 'cm' }, instock: [ { warehouse: 'A', qty: 40}]}"),
                Document.parse("{ item: 'postcard', status: 'A', size: { h: 10, w: 15.25, uom: 'cm' }, "
                        + "instock: [ { warehouse: 'B', qty: 15 }, { warehouse: 'C', qty: 35 } ] }")
        ));
    }

    /**
     * 查询返回所有的字段
     *
     * @param mongoCollection
     */
    public void queryAllFields(MongoCollection mongoCollection) {
        FindIterable findIterable = mongoCollection.find(eq("status", "A"));
        MongoCursor mongoCursor = findIterable.iterator();
        while (mongoCursor.hasNext()) {
            Document document = (Document) mongoCursor.next();
            System.out.println(document.toJson());
        }
    }

    /**
     * 查询返回指定的字段和_id
     *
     * @param mongoCollection
     */
    public void querySpecifiedFields(MongoCollection mongoCollection) {
        FindIterable findIterable = mongoCollection.find(eq("status", "A")).projection(include("item", "status"));
        MongoCursor mongoCursor = findIterable.iterator();
        while (mongoCursor.hasNext()) {
            Document document = (Document) mongoCursor.next();
            System.out.println(document.toJson());
        }
    }

    /**
     * 查询返回指定的字段，排除_id
     *
     * @param mongoCollection
     */
    public void querySpecifiedFields2(MongoCollection mongoCollection) {
        FindIterable findIterable = mongoCollection.find(eq("status", "A")).projection(fields(include("item", "status"), excludeId()));
        MongoCursor mongoCursor = findIterable.iterator();
        while (mongoCursor.hasNext()) {
            Document document = (Document) mongoCursor.next();
            System.out.println(document);
        }
    }

    /**
     * 查询返回排除字段以外的其他所有字段
     *
     * @param mongoCollection
     */
    public void querySpecifiedFieldsOnExclude(MongoCollection mongoCollection) {
        FindIterable findIterable = mongoCollection.find(eq("status", "A")).projection(exclude("status", "item"));
        MongoCursor mongoCursor = findIterable.iterator();
        while (mongoCursor.hasNext()) {
            Document document = (Document) mongoCursor.next();
            System.out.println(document);
        }
    }

    /**
     * 指定嵌套文档中返回的字段
     *
     * @param mongoCollection
     */
    public void querySpecifiedFieldsOnEmbedded(MongoCollection mongoCollection) {
        FindIterable findIterable = mongoCollection.find(eq("status", "A")).projection(include("item", "status", "size.uom"));
        MongoCursor mongoCursor = findIterable.iterator();
        while (mongoCursor.hasNext()) {
            Document document = (Document) mongoCursor.next();
            System.out.println(document);
        }
    }

    /**
     * 指定嵌套文档中排除返回字段
     *
     * @param mongoCollection
     */
    public void suppressSpecificFieldsOnEmbendded(MongoCollection mongoCollection) {
        FindIterable findIterable = mongoCollection.find(eq("status", "A")).projection(exclude("size.uom", "instock.qty"));
        MongoCursor mongoCursor = findIterable.iterator();
        while (mongoCursor.hasNext()) {
            Document document = (Document) mongoCursor.next();
            System.out.println(document.toJson());
        }
    }

    /**
     * 指定数组中返回的字段
     *
     * @param mongoCollection
     */
    public void projectionOnEmbeddedInArray(MongoCollection mongoCollection) {
        FindIterable findIterable = mongoCollection.find(eq("status", "A")).projection(include("item", "status", "instock.qty"));
        MongoCursor mongoCursor = findIterable.iterator();
        while (mongoCursor.hasNext()) {
            Document document = (Document) mongoCursor.next();
            System.out.println(document.toJson());
        }
    }

    /**
     * 指定数组中返回的元素
     *
     * @param mongoCollection
     */
    public void querySpecifiedArrayElements(MongoCollection mongoCollection) {
        FindIterable findIterable = mongoCollection.find(eq("status", "A")).projection(fields(include("item", "status"), slice("instock", -1)));
        MongoCursor mongoCursor = findIterable.iterator();
        while (mongoCursor.hasNext()) {
            Document document = (Document) mongoCursor.next();
            System.out.println(document.toJson());
        }
    }

    public static void main(String[] args) {
        QuerySpecifiedFields querySpecifiedFields = new QuerySpecifiedFields();
//        querySpecifiedFields.queryAllFields(mongoCollection);
//        querySpecifiedFields.querySpecifiedFields(mongoCollection);
//        querySpecifiedFields.querySpecifiedFields2(mongoCollection);
//        querySpecifiedFields.querySpecifiedFieldsOnExclude(mongoCollection );
//        querySpecifiedFields.querySpecifiedFieldsOnEmbedded(mongoCollection);
//        querySpecifiedFields.querySpecifiedArrayElements(mongoCollection);
//        querySpecifiedFields.suppressSpecificFieldsOnEmbendded(mongoCollection);
        querySpecifiedFields.projectionOnEmbeddedInArray(mongoCollection);
    }
}
